package com.web.kdl.service.excel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.web.kdl.common.result.CommonResult;
import com.web.kdl.dao.maDataReport.DataReportDao;
import com.web.kdl.entity.historyEvent.HistoryEvent;
import com.web.kdl.entity.maDataReport.DataReport;
import com.web.kdl.pojo.Vo.ExportTaskVO;
import com.web.kdl.pojo.excel.DataReportExcel;
import com.web.kdl.pojo.excel.HistoryEventExcel;
import com.web.kdl.pojo.form.DataReportForm;
import com.web.kdl.pojo.form.ExcelForm;
import com.web.kdl.pojo.form.HistoryEventForm;
import com.web.kdl.util.TableNameUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;

/**
 * @Author： shulibin
 * @Date： 2025/8/25 14:37
 * @Describe：
 */
@Slf4j
@Service
public class IExcelServiceImpl implements ExcelService{

    @Resource
    DataReportDao dataReportDao;
    
    @Resource
    ExportTaskManager taskManager;
    @Override
    public void exportHistoryEventExcel(List<HistoryEvent> historyEvent, ExcelForm form) {
        exportExcel(
                historyEvent,
                form,
                HistoryEventExcel.class,
                "历史事件"
        );
    }

    @Override
    public void exportDataReportExcel(List<DataReport> dataReport, ExcelForm form) {
        exportExcel(
                dataReport,
                form,
                DataReportExcel.class,
                "数据报表"
        );
    }

    @Override
    @Async
    public void exportDataReportExcelAsync(String taskId, String tempTable, String minuteTable, DataReportForm form) {
        long startTime = System.currentTimeMillis();
        String filePath = form.getFilePath();
        File file = new File(filePath);
        String fileName = file.getName();
        log.info("任务 {} 开始执行，文件路径：{}",
                taskId, filePath);
        
        // 更新任务状态为处理中
        taskManager.updateProcessing(taskId);
        
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        
        int totalRows = 0;
        try (ExcelWriter excelWriter = EasyExcel.write(filePath, DataReportExcel.class).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet("数据报表").build();
            List<DataReport> buffer = new ArrayList<>(1000);
            final int[] rowCount = {0};

            ResultHandler<DataReport> handler = resultContext -> {
                buffer.add(resultContext.getResultObject());
                rowCount[0]++;
                if (buffer.size() >= 1000) {
                    excelWriter.write(new ArrayList<>(buffer), writeSheet);
                    buffer.clear();
                }
            };
            if (tempTable != null)
            dataReportDao.streamSelectByTime(tempTable, form, handler);
            if (minuteTable != null)
            dataReportDao.streamSelectByTime(minuteTable, form, handler);

            // 写入剩余数据
            if (!buffer.isEmpty()) {
                excelWriter.write(buffer, writeSheet);
            }
            
            totalRows = rowCount[0];
            long endTime = System.currentTimeMillis();
            log.info("任务 {} 执行成功，共 {} 行数据，耗时：{} ms", 
                    taskId, totalRows, (endTime - startTime));
            
            // 更新任务状态为成功
            taskManager.updateSuccess(taskId, filePath, fileName, totalRows, startTime);
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("任务 {} 执行失败，耗时：{} ms", taskId, (endTime - startTime), e);
            
            // 更新任务状态为失败
            taskManager.updateFailed(taskId, e.getMessage(), startTime);
        }
    }

    @Override
    public void exportHistoryEventExcelAsync(String taskId,List<String> statusTableList, ExcelForm form) {
        long startTime = System.currentTimeMillis();
        String filePath = form.getFilePath();
        File file = new File(filePath);
        String fileName = file.getName();
        log.info("任务 {} 开始执行，文件路径：{}",
                taskId, filePath);
        // 更新任务状态为处理中
        taskManager.updateProcessing(taskId);

        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        int totalRows = 0;
        try (ExcelWriter excelWriter = EasyExcel.write(filePath, HistoryEventExcel.class).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet("历史事件").build();
            List<HistoryEvent> buffer = new ArrayList<>(1000);
            final int[] rowCount = {0};

            ResultHandler<HistoryEvent> handler = resultContext -> {
                buffer.add(resultContext.getResultObject());
                rowCount[0]++;
                if (buffer.size() >= 1000) {
                    excelWriter.write(new ArrayList<>(buffer), writeSheet);
                    buffer.clear();
                }
            };
            if (statusTableList.size()!=0)
                dataReportDao.streamSelectTableListByTime(statusTableList, form.getStartTime(), form.getEndTime(), handler);


            // 写入剩余数据
            if (!buffer.isEmpty()) {
                excelWriter.write(buffer, writeSheet);
            }

            totalRows = rowCount[0];
            long endTime = System.currentTimeMillis();
            log.info("任务 {} 执行成功，共 {} 行数据，耗时：{} ms",
                    taskId, totalRows, (endTime - startTime));

            // 更新任务状态为成功
            taskManager.updateSuccess(taskId, filePath, fileName, totalRows, startTime);

        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("任务 {} 执行失败，耗时：{} ms", taskId, (endTime - startTime), e);

            // 更新任务状态为失败
            taskManager.updateFailed(taskId, e.getMessage(), startTime);
        }
    }

    @Override
    public CommonResult queryExportTask(String taskId) {
        ExportTaskVO task = taskManager.getTask(taskId);
        if (task == null) {
            return CommonResult.error("任务不存在");
        }
        return CommonResult.success(task);
    }

    /**
     * 通用 Excel 导出方法（消除冗余逻辑）
     * @param dataList 数据列表
     * @param form 表单参数
     * @param excelClass Excel 数据模型类
     * @param sheetName sheet 名称
     */
    private <T> void exportExcel(
            List<T> dataList,
            ExcelForm form,
            Class<?> excelClass,
            String sheetName
    ) {
        // 1. 检查是否导出
        Boolean exportFile = Optional.ofNullable(form.getExportFile()).orElse(false);
        if (!exportFile) return;

        // 2. 获取文件路径并创建目录
        String filePath = form.getFilePath();
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        // 3. 执行导出并处理异常
        try {
            EasyExcel.write(filePath, excelClass)
                    .autoCloseStream(true)
                    .sheet(sheetName)
                    .doWrite(dataList);
        } catch (Exception e) {
            log.error("Excel导出失败，路径：{}", filePath, e);
        }
    }



}
